package rabbit.flt.test.webflux.reactor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.concurrent.locks.LockSupport;

@RestController
@RequestMapping("/reactor")
public class ReactorController {

    @Autowired
    protected ReactorService reactorService;

    /**
     * service是 异步方法
     *
     * @return
     */
    @GetMapping("/reactorSleep")
    public Mono<Void> reactorSleep() {
        return reactorService.reactorSleep(10).then();
    }

    /**
     * service是 常规方法
     *
     * @return
     */
    @GetMapping("/normalSleep")
    public Mono<Void> normalSleep() {
        reactorService.normalSleep(10);
        return Mono.empty();
    }

    /**
     * service和controller 都是常规方法
     *
     * @return
     */
    @GetMapping("/normal")
    void normal() {
        reactorService.normalSleep(10);
    }

    /**
     * 多次调用
     *
     * @return
     */
    @GetMapping("/multiCall")
    public Mono<Void> multiCall() {
        return reactorService.multiCall();
    }

    @GetMapping("/multiFluxCall")
    public Mono<Void> multiFluxCall() {
        return reactorService.multiFluxCall();
    }


    /**
     * 多次调用
     *
     * @return
     */
    @GetMapping("/monoError")
    public Mono<Void> monoError() {
        return reactorService.monoError();
    }

    @GetMapping("/fluxError")
    public Flux<Void> fluxError() {
        return reactorService.fluxError();
    }

    @GetMapping("/fluxData")
    public Flux<String> fluxData() {
        return Flux.just("hello");
    }

    @GetMapping("/fluxData2")
    public Flux<Mono<String>> fluxData2() {
        return Flux.just(Mono.just("abc"));
    }

    @GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> sse() {
        return Flux.fromIterable(Arrays.asList(1, 2, 3)).map(v -> {
            LockSupport.parkNanos(1000000000l);
            return "sse-" + v;
        });
    }
}
